home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Source.bin / StatusScroller.java < prev    next >
Text File  |  1998-10-12  |  18KB  |  656 lines

  1. package symantec.itools.awt.util;
  2.  
  3. import java.applet.*;
  4. import java.beans.PropertyVetoException;
  5. import java.beans.PropertyChangeListener;
  6. import java.beans.VetoableChangeListener;
  7. import java.beans.Beans;
  8.  
  9.  
  10. //  Created and implemented by Levi Brown, Symantec Macintosh Internet Tools.
  11. //     04/11/97    LAB    Checked it in
  12. //     04/17/97    LAB    Changed a few names to comply with Java standards.
  13. //                Added automatic initialization of the applet context in the constructor.
  14. //                Changed the function comment style to comply with JavaDoc standards.
  15. //                Took out some unnecessary code in setAppletContext(Applet a).
  16. //                Reorganized the code, to group public and private methods separately.
  17. //                Removed some unnecessary import statements.
  18. //                Fixed a bug in setAppletContext(Applet a) that could cause a NullPointerException.
  19. //                Added set/getAutoStart(boolean f) to allow the scrolling to occur without a direct call to start().
  20. //                Changed the default state of execute to true, so scrolling would automatically occur.
  21. //     06/02/97    LAB    Updated to Java 1.1
  22. //  09/09/98    MSH Changed class so that it no longer creates threads at design-time, #62541
  23.  
  24. /**
  25.  * Displays a scrolling message in the status window of a browser or
  26.  * applet viewer.
  27.  *
  28.  * @version 1.1, June 2, 1997
  29.  * @author Symantec
  30.  */
  31. public class StatusScroller implements Runnable
  32. {
  33.     /**
  34.      * Constructs a StatusScroller.
  35.      * By default, the message (set by the setString() method) will scroll
  36.      * right-to-left, repeat, and will completely scroll off before scrolling
  37.      * on again.
  38.      * @see #setString
  39.      */
  40.     public StatusScroller()
  41.     {
  42.         isRightToLeft    = true;
  43.         isRepeat        = true;
  44.         isScrollClean    = true;
  45.         execute            = true;
  46.         loopFlag        = false;
  47.         statusString    = null;
  48.         delay            = 100;
  49.         if ( !Beans.isDesignTime() )
  50.             thread            = new Thread(this);
  51.  
  52.         //Initalize the context variable
  53.         try
  54.         {
  55.             setAppletContext(symantec.itools.lang.Context.getApplet());
  56.         }
  57.         catch(Exception e)
  58.         {
  59.             e.printStackTrace();
  60.         }
  61.             
  62.         if ( !Beans.isDesignTime() )
  63.         {
  64.             thread.start();
  65.         }
  66.  
  67.     }
  68.  
  69.  
  70.     //***** Public Methods *****//
  71.  
  72.     /**
  73.      * Sets the string to be scrolled in the browser or applet viewer.
  74.      *
  75.      * @param s the message to scroll
  76.      * @see #getString
  77.      *
  78.      * @exception PropertyVetoException
  79.      * if the specified property value is unacceptable
  80.      */
  81.     public void setString(String s) throws PropertyVetoException
  82.     {
  83.         if (context == null) {
  84.             //Initalize the context variable
  85.             try
  86.             {
  87.                 setAppletContext(symantec.itools.lang.Context.getApplet());
  88.             }
  89.             catch(Exception e)
  90.             {
  91.                 e.printStackTrace();
  92.             }
  93.         }
  94.         
  95.         if(!symantec.itools.util.GeneralUtils.objectsEqual(statusString, s))
  96.         {
  97.             String oldValue = statusString;
  98.  
  99.             vetos.fireVetoableChange("String", oldValue, s);
  100.  
  101.             statusString = s;
  102.             index = 0;
  103.  
  104.             if(statusString == null || statusString.equals(""))
  105.             {
  106.                 statusString =    null;
  107.                 workingBuffer = null;
  108.                 wblength = 0;
  109.                 sslength = 0;
  110.                 if(execute)
  111.                     clear();
  112.             }
  113.             else
  114.             {
  115.                 sslength = statusString.length();
  116.                 updateWorkingBuffer();
  117.             }
  118.  
  119.             changes.firePropertyChange("String", oldValue, statusString);
  120.         }
  121.     }
  122.  
  123.     /**
  124.      * Gets the string being scrolled.
  125.      * @return the current scroll string
  126.      * @see #setString
  127.      */
  128.     public String getString()
  129.     {
  130.         return statusString;
  131.     }
  132.  
  133.     /**
  134.      * Controls the direction the text will scroll.
  135.      * @param b the direction to scroll the text;
  136.      * true for right-to-left, false for left-to-right
  137.      * @see #getRightToLeft
  138.      *
  139.      * @exception PropertyVetoException
  140.      * if the specified property value is unacceptable
  141.      */
  142.     public void setRightToLeft(boolean b) throws PropertyVetoException
  143.     {
  144.         Boolean oldValue = new Boolean(isRightToLeft);
  145.         Boolean newValue = new Boolean(b);
  146.  
  147.         vetos.fireVetoableChange("RightToLeft", oldValue, newValue);
  148.  
  149.         isRightToLeft = b;
  150.  
  151.         changes.firePropertyChange("RightToLeft", oldValue, newValue);
  152.     }
  153.  
  154.     /**
  155.      * Gets the direction the text will scroll.
  156.      * @return true if the text will scroll right-to-left,
  157.      * false if the text will scroll left-to-right
  158.      * @see #setRightToLeft
  159.      */
  160.     public boolean isRightToLeft()
  161.     {
  162.         return isRightToLeft;
  163.     }
  164.  
  165.     /**
  166.      * @deprecated
  167.      * @see #isRightToLeft
  168.      */
  169.     public boolean getRightToLeft()
  170.     {
  171.         return isRightToLeft();
  172.     }
  173.  
  174.     /**
  175.      * Controls whether text will scroll completely off before scrolling on
  176.      * again.
  177.      * @param b if true the text will scroll completely off before scrolling
  178.      * on again, if false the text will scroll without any gap
  179.      * @see #isScrollClean
  180.      *
  181.      * @exception PropertyVetoException
  182.      * if the specified property value is unacceptable
  183.      */
  184.     public void setScrollClean(boolean b) throws PropertyVetoException
  185.     {
  186.         if(isScrollClean != b)
  187.         {
  188.             Boolean oldValue = new Boolean(isScrollClean);
  189.             Boolean newValue = new Boolean(b);
  190.  
  191.             vetos.fireVetoableChange("ScrollClean", oldValue, newValue);
  192.  
  193.             isScrollClean = b;
  194.             updateWorkingBuffer();
  195.  
  196.             changes.firePropertyChange("ScrollClean", oldValue, newValue);
  197.         }
  198.     }
  199.  
  200.     /**
  201.      * Gets whether text will scroll completely off before scrolling on
  202.      * again.
  203.      * @return true if the text will scroll completely off before scrolling
  204.      * on again, false if the text will scroll without any gap
  205.      * @see #setScrollClean
  206.      */
  207.     public boolean isScrollClean()
  208.     {
  209.         return isScrollClean;
  210.     }
  211.  
  212.     /**
  213.      * @deprecated
  214.      * @see #isScrollClean
  215.      */
  216.     public boolean getScrollClean()
  217.     {
  218.         return isScrollClean();
  219.     }
  220.  
  221.     /**
  222.      * Controls whether scrolling will automatically start when the applet is loaded.
  223.      * @param f if true the text will start scrolling as soon as the applet
  224.      * is loaded, if false the text will not scroll until start() is called
  225.      * @see #isAutoStart
  226.      * @see #start
  227.      * @see #stop
  228.      *
  229.      * @exception PropertyVetoException
  230.      * if the specified property value is unacceptable
  231.      */
  232.     public void setAutoStart(boolean f) throws PropertyVetoException
  233.     {
  234.         Boolean oldValue = new Boolean(isAutoStart());
  235.         Boolean newValue = new Boolean(f);
  236.  
  237.         vetos.fireVetoableChange("AutoStart", oldValue, newValue);
  238.  
  239.         if(f)
  240.             start();
  241.         else
  242.             stop();
  243.  
  244.         changes.firePropertyChange("AutoStart", oldValue, newValue);
  245.     }
  246.  
  247.     /**
  248.      * Gets whether scrolling will automatically start when the applet is loaded.
  249.      * @return true if the text will start scrolling as soon as the applet is loaded,
  250.      * false if the text will not scroll until start() is called
  251.      * @see #setAutoStart
  252.      * @see #start
  253.      * @see #stop
  254.      */
  255.     public boolean isAutoStart()
  256.     {
  257.         return execute;
  258.     }
  259.  
  260.     /**
  261.      * @deprecated
  262.      * @see #isAutoStart
  263.      */
  264.     public boolean getAutoStart()
  265.     {
  266.         return isAutoStart();
  267.     }
  268.  
  269.     /**
  270.      * Controls whether text will repeatedly scroll or just scroll once.
  271.      * @param f if true the text will scroll over and over,
  272.      * if false the text will scroll off and back on, then stop
  273.      * @see #isRepeat
  274.      *
  275.      * @exception PropertyVetoException
  276.      * if the specified property value is unacceptable
  277.      */
  278.     public void setRepeat(boolean f) throws PropertyVetoException
  279.     {
  280.         Boolean oldValue = new Boolean(isRepeat);
  281.         Boolean newValue = new Boolean(f);
  282.  
  283.         vetos.fireVetoableChange("Repeat", oldValue, newValue);
  284.  
  285.         isRepeat = f;
  286.  
  287.         changes.firePropertyChange("Repeat", oldValue, newValue);
  288.     }
  289.  
  290.     /**
  291.      * Gets whether text will repeatedly scroll or just scroll once.
  292.      * @return true if the text will scroll over and over,
  293.      * false if the text will scroll off and back on, then stop
  294.      * @see #setRepeat
  295.      */
  296.     public boolean isRepeat()
  297.     {
  298.         return isRepeat;
  299.     }
  300.  
  301.     /**
  302.      * @deprecated
  303.      * @see #isRepeat
  304.      */
  305.     public boolean getRepeat()
  306.     {
  307.         return isRepeat();
  308.     }
  309.  
  310.     /**
  311.      * Sets the time between the display of each character in milliseconds.
  312.      * The minimum delay is 30 milliseconds.
  313.      * @param d the delay, in milliseconds
  314.      * @see #getDelay
  315.      *
  316.      * @exception PropertyVetoException
  317.      * if the specified property value is unacceptable
  318.      */
  319.     public void setDelay(int d) throws PropertyVetoException
  320.     {
  321.         int temp = 0;
  322.  
  323.         if(d < 30)
  324.             temp = 30;
  325.         else
  326.             temp = d;
  327.  
  328.         Integer oldValue = new Integer(delay);
  329.         Integer newValue = new Integer(temp);
  330.  
  331.         vetos.fireVetoableChange("Delay", oldValue, newValue);
  332.  
  333.         delay = temp;
  334.  
  335.         changes.firePropertyChange("Delay", oldValue, newValue);
  336.     }
  337.  
  338.     /**
  339.      * Gets the time between the display of each character in milliseconds.
  340.      * @return the delay, in milliseconds
  341.      * @see #setDelay
  342.      */
  343.     public int getDelay()
  344.     {
  345.         return delay;
  346.     }
  347.  
  348.     /**
  349.      * Sets the AppletContext that has the status area for scrolling text.
  350.      * Note: this overrides the automatically set AppletContext.
  351.      *
  352.      * @param c the new AppletContext
  353.      * @see #setAppletContext(java.applet.Applet)
  354.      *
  355.      * @exception PropertyVetoException
  356.      * if the specified property value is unacceptable
  357.      */
  358.     public void setAppletContext(AppletContext c) throws PropertyVetoException
  359.     {
  360.         AppletContext oldValue = context;
  361.  
  362.         vetos.fireVetoableChange("AppletContext", oldValue, c);
  363.  
  364.         context = c;
  365.  
  366.         changes.firePropertyChange("AppletContext", oldValue, c);
  367.     }
  368.  
  369.     /**
  370.      * Sets the AppletContext that has the status area for scrolling text.
  371.      * This version takes an Applet object and gets the needed AppletContext from that.
  372.      * Note: this overrides the automatically set AppletContext.
  373.      *
  374.      * @param a the Applet with the AppletContext to use
  375.      * @see #setAppletContext(java.applet.AppletContext)
  376.      *
  377.      * @exception PropertyVetoException
  378.      * if the specified property value is unacceptable
  379.      */
  380.     public void setAppletContext(Applet a) throws PropertyVetoException
  381.     {
  382.         if(a == null)
  383.             setAppletContext((AppletContext)null);
  384.         else
  385.             setAppletContext(a.getAppletContext());
  386.     }
  387.  
  388.     /**
  389.      * Starts the status text scrolling.
  390.      * @see #stop
  391.      * @see #run
  392.      */
  393.     public void start()
  394.     {
  395.         execute = true;
  396.         if ( !Beans.isDesignTime() )
  397.             thread.resume();
  398.     }
  399.  
  400.     /**
  401.      * Stops the status text scrolling.
  402.      * @see #start
  403.      */
  404.     public void stop()
  405.     {
  406.         execute   = false;
  407.     }
  408.  
  409.     /**
  410.      * Clears the status area.
  411.      * Note: this does not clear the string to scroll,
  412.      * it just clears the status area in the current AppletContext.
  413.      */
  414.     public void clear()
  415.     {
  416.         if(context != null)
  417.         {
  418.             //Display an empty string
  419.             context.showStatus("");
  420.         }
  421.     }
  422.  
  423.     /**
  424.      * The body of the StatusScroller Thread.
  425.      * This method is called by the Java Virtual Machine in response to a
  426.      * call to the start method of this object.
  427.      */
  428.     public void run()
  429.     {
  430.  
  431.         String workingString = null;
  432.         int loopIndicator;
  433.  
  434.         if(!execute && !Beans.isDesignTime() ) thread.suspend();
  435.         try
  436.         {
  437.             while(true)
  438.             {
  439.                 do
  440.                 {
  441.                        //loopIndicator = index;
  442.                     if ( !Beans.isDesignTime() )
  443.                         thread.sleep(delay);
  444.  
  445.                     if (execute)
  446.                     {
  447.                         //Get the string to display
  448.                         workingString = scrollString();
  449.                         if (context != null && workingString != null)
  450.                         {
  451.                             //Display the string
  452.                             context.showStatus(workingString);
  453.                         }
  454.                     }
  455.                 }
  456.                 //Keep scrolling until an exit condition is met
  457.                 while (index != 0 || isRepeat);
  458.  
  459.                 if ( !Beans.isDesignTime() )
  460.                     thread.suspend();
  461.             }
  462.         }
  463.         catch (InterruptedException e)
  464.         {
  465.         }
  466.     }
  467.  
  468.     /**
  469.      * Adds a listener for all property change events.
  470.      * @param listener the listener to add
  471.      * @see #removePropertyChangeListener
  472.      */
  473.     public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
  474.     {
  475.         changes.addPropertyChangeListener(listener);
  476.     }
  477.  
  478.     /**
  479.      * Removes a listener for all property change events.
  480.      * @param listener the listener to remove
  481.      * @see #addPropertyChangeListener
  482.      */
  483.     public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
  484.     {
  485.         changes.removePropertyChangeListener(listener);
  486.     }
  487.  
  488.     /**
  489.      * Adds a listener for all vetoable property change events.
  490.      * @param listener the listener to add
  491.      * @see #removeVetoableChangeListener
  492.      */
  493.     public synchronized void addVetoableChangeListener(VetoableChangeListener listener)
  494.     {
  495.         vetos.addVetoableChangeListener(listener);
  496.     }
  497.  
  498.     /**
  499.      * Removes a listener for all vetoable property change events.
  500.      * @param listener the listener to remove
  501.      * @see #addVetoableChangeListener
  502.      */
  503.     public synchronized void removeVetoableChangeListener(VetoableChangeListener listener)
  504.     {
  505.         vetos.removeVetoableChangeListener(listener);
  506.     }
  507.  
  508.        //***** Private Methods *****//
  509.  
  510.     /**
  511.      * Handles the manipulation of the string buffer to give the
  512.      * desired scrolling effect.
  513.      * @return the string to be displayed
  514.      * @see #run
  515.      * @see #setRightToLeft
  516.      * @see #getRightToLeft
  517.      */
  518.     protected String scrollString()
  519.     {
  520.         //If the string is null
  521.         if(workingBuffer == null)
  522.             return null;
  523.         //If there is only one character
  524.         if(wblength < 2)
  525.             return(workingBuffer.toString());
  526.  
  527.         char ch, temp[];
  528.         //Allocate space for the rest of the characters
  529.         temp = new char[wblength - 1];
  530.  
  531.         if(isRightToLeft)
  532.         {
  533.             //Store the first character
  534.             ch = workingBuffer.charAt(0);
  535.             //Store the rest of the characters
  536.             workingBuffer.getChars(1, wblength, temp, 0);
  537.             //Shift the rest of the characters to the left one index
  538.             workingBuffer = new StringBuffer(new String(temp));
  539.             //Append the first character
  540.             workingBuffer = workingBuffer.append(ch);
  541.             //Keep track of where the original first character is
  542.             index++;
  543.             if(index > wblength -1)
  544.                 index = 0;
  545.         }
  546.         else
  547.         {
  548.             //Store the last character
  549.             ch = workingBuffer.charAt(wblength - 1);
  550.             //Store the rest of the characters
  551.             workingBuffer.getChars(0, wblength - 1, temp, 0);
  552.             //Place the last character at the beginning
  553.             workingBuffer = new StringBuffer("" + ch);
  554.             //Append the rest of the characters
  555.             workingBuffer = workingBuffer.append(temp);
  556.             //Keep track of where the original first character is
  557.             index--;
  558.             if(index < 0)
  559.                 index = wblength -1;
  560.         }
  561.  
  562.         //Return a window onto the modified string buffer to be displayed
  563.         return((workingBuffer.toString()).substring(0, sslength));
  564.     }
  565.  
  566.     /**
  567.      * Returns a String with howBig number of spaces as the content
  568.      * @param howBig the requested number of spaces
  569.      * @return a String with the requested number of spaces
  570.      */
  571.     protected String makePadding(int howBig)
  572.     {
  573.         StringBuffer str = new StringBuffer(0);
  574.  
  575.         for(int i = 0; i < howBig; ++i)
  576.             str.append(" ");
  577.         return(str.toString());
  578.     }
  579.  
  580.     /**
  581.      * Updates the string buffer depending on the current settings.
  582.      * @see #setScrollClean
  583.      */
  584.     protected void updateWorkingBuffer()
  585.     {
  586.         if(isScrollClean)
  587.         {
  588.             String temp = makePadding(sslength);
  589.             workingBuffer = new StringBuffer(statusString + temp);
  590.         }
  591.         else
  592.             workingBuffer = new StringBuffer(statusString);
  593.  
  594.         wblength = workingBuffer.length();
  595.     }
  596.  
  597.     /**
  598.      * If true, the text will scroll from the right to the left.
  599.      * @see #setRightToLeft
  600.      * @see #isRightToLeft
  601.      */
  602.     protected boolean isRightToLeft;
  603.     /**
  604.      * If true, the text will continue scrolling over and over.
  605.      * @see #setRepeat
  606.      * @see #isRepeat
  607.      */
  608.     protected boolean isRepeat;
  609.     /**
  610.      * If true, the text will scroll completely off before scrolling on again.
  611.      * @see #setScrollClean
  612.      * @see #isScrollClean
  613.      */
  614.     protected boolean isScrollClean;
  615.     /**
  616.      * The applet context that shows the status text.
  617.      */
  618.     protected AppletContext context;
  619.     /**
  620.      * The thread that handles scrolling the text.
  621.      * @see #start
  622.      * @see #stop
  623.      */
  624.     protected Thread thread;
  625.     /**
  626.      * The time between the display of each character in milliseconds.
  627.      * @see #setDelay
  628.      * @see #getDelay
  629.      */
  630.     protected int delay;
  631.     /**
  632.      * Working buffer length, in characters.
  633.      */
  634.     protected int wblength;
  635.     /**
  636.      * Status string length, in characters.
  637.      */
  638.     protected int sslength;
  639.     /**
  640.      * The zero-relative index of the original first character.
  641.      */
  642.     protected int index;
  643.     /**
  644.      * The string to scroll.
  645.      */
  646.     protected    String    statusString;
  647.     /**
  648.      * The string that gets scrolled.
  649.      */
  650.     protected StringBuffer    workingBuffer;
  651.  
  652.     private boolean execute, loopFlag;
  653.     private symantec.itools.beans.VetoableChangeSupport vetos = new symantec.itools.beans.VetoableChangeSupport(this);
  654.     private symantec.itools.beans.PropertyChangeSupport changes = new symantec.itools.beans.PropertyChangeSupport(this);
  655. }
  656.